/**
 * Copyright (c) 2017 ucsmy.com, All rights reserved.
 */
package itsm.isperp.module.controller.api.wechat.v2;

/**
 * @Description:
 * @Author: legen
 * @Created Date: 2017-10-31-0031.
 * @LastModifyDate: 2017-10-31-0031.
 * @LastModifyBy: legen
 * @Version:
 */

import itsm.isperp.framework.collection.tree.ITreeNode;
import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.module.entity.app.AppDepartment;
import itsm.isperp.module.entity.app.AppUser;
import itsm.isperp.module.entity.customer.CusCustomer;
import itsm.isperp.module.entity.report.ReportCheckinData;
import itsm.isperp.module.service.app.AppDepartmentService;
import itsm.isperp.module.service.app.AppUserService;
import itsm.isperp.module.service.customer.CusCustomerService;
import itsm.isperp.module.service.report.ReportCheckinDataService;

import java.lang.reflect.Type;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.mp.api.WxMpService;

import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;

/**
 * @Description:
 * @Author: legen
 * @Created Date: 2017-09-18-0018.
 * @LastModifyDate: 2017-09-18-0018.
 * @LastModifyBy: legen
 * @Version:
 */
@Controller
@RequestMapping("api/wechat/v2/wechat")
public class WechatController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(WechatController.class);

    private String corpid = ContextHolder.getConfigByKey("wechatCpAppId");
    private String corpAgentId = ContextHolder.getConfigByKey("wechatCpAgentId");
    private String corpsecret = ContextHolder.getConfigByKey("wechatCpAppSecret");

    public String departmentSecret = "ih-Skk7VpYK4j_mL8rCMeLXs8MK-6IIOaMylM0PhHZg";
    public String checkinSecret = "vy4-qngFIJaKAkyZTPXpYLd1LI5JAqZIZXsfwV-nLXg";

    @Autowired
    WxCpService wxCpService;

    private Gson createGson() {
        Gson gson = new GsonBuilder()
                .serializeNulls()
                .registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
                    @Override
                    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                        return new java.util.Date(json.getAsJsonPrimitive().getAsLong() * 1000);
                    }
                })
                .registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
                    @Override
                    public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
                        return new JsonPrimitive(src.getTime() / 1000);
                    }
                })
                .create();
        return gson;
    }

    private JSONObject httpGet(String url)
            throws Exception {
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Content-Type", "application/json; charset=UTF-8");

        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity entity = httpResponse.getEntity();

        String response = EntityUtils.toString(entity);
        JSONObject json = new JSONObject(response);

        return json;
    }

    private JSONObject httpPost(String url, Object param)
            throws Exception {
        Gson gson = this.createGson();
        String paramJson = gson.toJson(param);
        StringEntity stringEntity = new StringEntity(paramJson, "UTF-8");

        HttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
        httpPost.setEntity(stringEntity);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity entity = httpResponse.getEntity();

        String response = EntityUtils.toString(entity);
        JSONObject json = new JSONObject(response);

        return json;
    }

    /**
     * 获取accessToken
     */
    private JSONObject httpGetAccessToken(String secret)
            throws Exception {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + secret;
        try {
            return httpGet(url);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception("获取微信AccessToken失败，原因是：" + e.getMessage());
        }
    }

    /**
     * 获取accessToken
     */
    private String accessToken(HttpServletRequest request, String secret)
            throws Exception {

        ServletContext servletContext = request.getSession().getServletContext();
        Object accessTokenObj = servletContext.getAttribute("wxAccessToken" + secret);
        Object accessTokenTimeOutObj = servletContext.getAttribute("wxAccessTokenTimeOut" + secret);

        if (accessTokenObj != null || accessTokenTimeOutObj != null) {
            Date now = new Date();
            Date accessTokenTimeOut = (Date) accessTokenTimeOutObj;

            if (accessTokenTimeOut.after(now)) {
                return (String) accessTokenObj;
            }
        }

        JSONObject json = this.httpGetAccessToken(secret);
        String accessToken = json.getString("access_token");
        int expiresIn = json.getInt("expires_in");

        Date now = new Date();
        Date accessTokenTimeOut = new Date(now.getTime() + (expiresIn * 1000));
        servletContext.setAttribute("wxAccessToken" + secret, accessToken);
        servletContext.setAttribute("wxAccessTokenTimeOut" + secret, accessTokenTimeOut);

        return accessToken;
    }

    private String accessToken1(ServletContext servletContext, String secret)
            throws Exception {

        Object accessTokenObj = servletContext.getAttribute("wxAccessToken" + secret);
        Object accessTokenTimeOutObj = servletContext.getAttribute("wxAccessTokenTimeOut" + secret);

        if (accessTokenObj != null || accessTokenTimeOutObj != null) {
            Date now = new Date();
            Date accessTokenTimeOut = (Date) accessTokenTimeOutObj;

            if (accessTokenTimeOut.after(now)) {
                return (String) accessTokenObj;
            }
        }

        JSONObject json = this.httpGetAccessToken(secret);
        String accessToken = json.getString("access_token");
        int expiresIn = json.getInt("expires_in");

        Date now = new Date();
        Date accessTokenTimeOut = new Date(now.getTime() + (expiresIn * 1000));
        servletContext.setAttribute("wxAccessToken" + secret, accessToken);
        servletContext.setAttribute("wxAccessTokenTimeOut" + secret, accessTokenTimeOut);

        return accessToken;
    }

    private JSONObject getJsapiTicket(HttpServletRequest request)
            throws Exception {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + this.accessToken(request, this.corpsecret);
        try {
            return httpGet(url);
        } catch (Exception e) {

            logger.error(e.getMessage(), e);
            throw new Exception("获取微信JsapiTicket失败，原因是：" + e.getMessage());
        }
    }

    private String jsapiTicket(HttpServletRequest request)
            throws Exception {
        ServletContext servletContext = request.getSession().getServletContext();
        Object wxJsapiTicketObj = servletContext.getAttribute("wxJsapiTicket");
        Object wxJsapiTicketTimeOutObj = servletContext.getAttribute("wxJsapiTicketTimeOut");

        if (wxJsapiTicketObj != null || wxJsapiTicketTimeOutObj != null) {
            Date now = new Date();
            Date accessTokenTimeOut = (Date) wxJsapiTicketTimeOutObj;

            if (accessTokenTimeOut.after(now)) {
                return (String) wxJsapiTicketObj;
            }
        }

        JSONObject json = this.getJsapiTicket(request);
        String ticket = json.getString("ticket");
        int expiresIn = json.getInt("expires_in");

        Date now = new Date();
        Date jsapiTicketTimeOut = new Date(now.getTime() + (expiresIn * 1000));
        servletContext.setAttribute("wxJsapiTicket", ticket);
        servletContext.setAttribute("wxJsapiTicketTimeOut", jsapiTicketTimeOut);

        return ticket;
    }

    private String getSha1(String str) {
        if (null == str || 0 == str.length()) {
            return null;
        }
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));
            byte[] md = mdTemp.digest();
            int j = md.length;
            char[] buf = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }

    @RequestMapping("jssdk")
    @ResponseBody
    public Map<String, Object> jssdk(String url, HttpServletRequest request)
            throws Exception {

        String noncestr = UUID.randomUUID().toString();
        String ticket = this.jsapiTicket(request);
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);

        String noncestrParam = "noncestr=" + noncestr;
        String ticketParam = "jsapi_ticket=" + ticket;
        String timestampParam = "timestamp=" + timestamp;
        String urlParam = "url=" + url;

        String[] arrParam = new String[]{noncestrParam, ticketParam, timestampParam, urlParam};
        Arrays.sort(arrParam);
        String param = "";
        //String param = String.join("&", arrParam);
        for (String s : arrParam) {
            param += "&" + s;
        }
        param = param.substring(1, param.length());
        String signature = this.getSha1(param);

        Map<String, Object> map = new HashMap<>();
        map.put("appId", corpid);
        map.put("timestamp", timestamp);
        map.put("nonceStr", noncestr);
        map.put("signature", signature.toLowerCase());

        return map;
    }

    /**
     * 获取当前用户
     */
    @RequestMapping("getCurrentUser")
    @ResponseBody
    public String getCurrentUser(HttpServletRequest request, String code)
            throws Exception {

        String accessToken = this.accessToken(request, this.corpsecret);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" + accessToken + "&code=" + code;

        String jsonString = "";
        try {
            JSONObject json = httpGet(url);
            jsonString = json.toString();
            return json.getString("UserId");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception("获取微信AccessToken失败，原因是：" + jsonString);
        }
    }

    @Autowired
    private CusCustomerService cusCustomerService;

    @Autowired
    private AppDepartmentService appDepartmentService;

    @Autowired
    private AppUserService appUserService;

    @RequestMapping("syncDepartmentAndUser")
    @ResponseBody
    public void syncDepartmentAndUser(HttpServletRequest request)
            throws Exception {
        Map<String, Integer> departmentMap = new HashedMap();

        List<Integer> departmentIds = this.syncDepartment(request, departmentMap);
        this.syncUser(request, departmentMap);
        this.deleteDepartments(request, departmentIds);
    }

    private List<Integer> syncDepartment(HttpServletRequest request, Map<String, Integer> departmentMap)
            throws Exception {

        JqGridRequest jqGridRequest = new JqGridRequest();
        jqGridRequest.addFilterRule("category", JqGridFilterRuleOp.eq, "company");
        List<CusCustomer> companys = cusCustomerService.findAll(jqGridRequest);

        List<AppDepartment> all = appDepartmentService.getTree(null, false, "id", "name", "parent_id", "order_num");
        List<AppDepartment> departments = new ArrayList<>();
        for (CusCustomer company : companys) {
            for (AppDepartment department : all) {
                if (company.getName().equals(department.getName())) {
                    departments.add(department);
                }
            }
        }

        String departmentUrl = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=" + this.accessToken(request, this.departmentSecret);
        String wDepartmentString = httpGet(departmentUrl).getString("department");
        Type type = new TypeToken<LinkedList<WechatDepartment>>() {
        }.getType();
        Gson gson = this.createGson();
        List<WechatDepartment> wDepartments = gson.fromJson(wDepartmentString, type);

        for (ITreeNode node : departments) {
            AppDepartment department = (AppDepartment) node;
            syncDepartment(request, department, wDepartments, 1, departmentMap);
        }

        List<Integer> departmentIds = new ArrayList<>();
        for (WechatDepartment wDepartment : wDepartments) {
            if (wDepartment.getId() != 1) {
                departmentIds.add(wDepartment.getId());
            }
        }
        return departmentIds;
    }

    public void syncDepartment(HttpServletRequest request, AppDepartment department, List<WechatDepartment> wDepartments, Integer parentid, Map<String, Integer> departmentMap)
            throws Exception {

        int wDepartmentId = getDepartmentId(request, department, wDepartments, parentid);
        departmentMap.put(department.getId(), wDepartmentId);

        if (department.getChildren() != null) {
            for (ITreeNode node : department.getChildren()) {
                AppDepartment child = (AppDepartment) node;
                syncDepartment(request, child, wDepartments, wDepartmentId, departmentMap);
            }
        }
    }

    private int getDepartmentId(HttpServletRequest request, AppDepartment department, List<WechatDepartment> wDepartments, Integer parentid)
            throws Exception {

        int orderNum = 10000 - department.getOrderNum();

        for (int i = 0; i < wDepartments.size(); i++) {
            WechatDepartment wDepartment = wDepartments.get(i);

            if (parentid == wDepartment.getParentid() && department.getName().equals(wDepartment.getName())) {
                if (orderNum != wDepartment.getOrder()) {
                    updateDepartment(request, wDepartment.getId(), parentid, department.getName(), orderNum);
                }
                wDepartments.remove(i);
                return wDepartment.getId();
            }
        }

        int wId = addDepartment(request, parentid, department.getName(), orderNum);
        return wId;
    }

    private List<WechatUser> getWechatUsers(HttpServletRequest request)
            throws Exception {
        String userUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=" + this.accessToken(request, this.departmentSecret) + "&department_id=1&fetch_child=1";
        String wUserString = httpGet(userUrl).getString("userlist");
        Type type = new TypeToken<LinkedList<WechatUser>>() {
        }.getType();
        Gson gson = this.createGson();
        return gson.fromJson(wUserString, type);
    }

    private List<WechatUser> getWechatUsers1(ServletContext servletContext)
            throws Exception {
        String userUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=" + this.accessToken1(servletContext, this.departmentSecret) + "&department_id=1&fetch_child=1";
        String wUserString = httpGet(userUrl).getString("userlist");
        Type type = new TypeToken<LinkedList<WechatUser>>() {
        }.getType();
        Gson gson = this.createGson();
        return gson.fromJson(wUserString, type);
    }

    private void syncUser(HttpServletRequest request, Map<String, Integer> departmentMap)
            throws Exception {

        JqGridRequest jqGridRequest = new JqGridRequest();
        jqGridRequest.addFilterRule("category", JqGridFilterRuleOp.eq, "company");
        List<CusCustomer> companys = cusCustomerService.findAll(jqGridRequest);

        List<AppUser> users = new ArrayList<>();
        for (CusCustomer company : companys) {

            JqGridRequest userJqGridRequest = new JqGridRequest();
            userJqGridRequest.addFilterRule("department_treenode_name_path", JqGridFilterRuleOp.bw, "/" + company.getName());
            List<Map<String, Object>> companyUser = appUserService.findAllDetailByRequest(userJqGridRequest);
            for (Map<String, Object> map : companyUser) {

                AppUser user = new AppUser();
                user.setName((String) map.get("name"));
                user.setFullname((String) map.get("fullname"));
                user.setMobile((String) map.get("mobile"));
                user.setAppDepartmentId((String) map.get("app_department_id"));
                user.setPosition((String) map.get("position"));
                user.setGender((String) map.get("gender"));
                user.setEmail((String) map.get("email"));
                users.add(user);
            }
        }

        List<WechatUser> wUsers = getWechatUsers(request);
        for (AppUser user : users) {
            syncUser(request, user, wUsers, departmentMap);
        }

        List<String> userids = new ArrayList<>();
        for (WechatUser wUser : wUsers) {
            userids.add(wUser.getUserid());
        }
        this.deleteUser(request, userids);
    }

    private void syncUser(HttpServletRequest request, AppUser user, List<WechatUser> wUsers, Map<String, Integer> departmentMap)
            throws Exception {

        if (StringUtils.isBlank(user.getMobile()) && StringUtils.isBlank(user.getEmail())) {
            return;
        }

        int departmentId = departmentMap.get(user.getAppDepartmentId());
        String gender = "0";
        if (StringUtils.isNotBlank(user.getGender())) {
            gender = user.getGender().equals("男") ? "1" : "2";
        }
        if (user.getFullname() == null) {
            user.setFullname("");
        }
        if (user.getPosition() == null) {
            user.setPosition("");
        }
        if (user.getMobile() == null) {
            user.setMobile("");
        }
        if (user.getEmail() == null) {
            user.setEmail("");
        }

        for (int i = 0; i < wUsers.size(); i++) {
            WechatUser wUser = wUsers.get(i);

            if (user.getUsername().equals(wUser.getUserid())) {

                if (!user.getFullname().equals(wUser.getName())
                        || !user.getPosition().equals(wUser.getPosition())
                        || !gender.equals(wUser.getGender())
                        || !user.getMobile().equals(wUser.getMobile())
                        || !user.getEmail().equals(wUser.getEmail())
                        || !wUser.department.contains(departmentId)) {
                    this.updateUser(request, user.getUsername(), user.getFullname(), user.getMobile(), departmentId, user.getPosition(), gender, user.getEmail());
                }
                wUsers.remove(i);
                return;
            }
        }

        this.addUser(request, user.getUsername(), user.getFullname(), user.getMobile(), departmentId, user.getPosition(), gender, user.getEmail());
    }

    private int addDepartment(HttpServletRequest request, int parentid, String name, int order)
            throws Exception {

        String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create?access_token=" + this.accessToken(request, this.departmentSecret);

        WechatDepartment wechatDepartment = new WechatDepartment();
        wechatDepartment.setParentid(parentid);
        wechatDepartment.setName(name);
        wechatDepartment.setOrder(order);

        logger.info(String.format("微信添加部门请求：parentid %s name %s order %s", parentid, name, order));
        JSONObject jsonObject = httpPost(url, wechatDepartment);
        logger.info("微信添加部门响应：" + jsonObject);

        int id = jsonObject.getInt("id");
        return id;
    }

    private void updateDepartment(HttpServletRequest request, int id, int parentid, String name, int order)
            throws Exception {

        String url = "https://qyapi.weixin.qq.com/cgi-bin/department/update?access_token=" + this.accessToken(request, this.departmentSecret);

        WechatDepartment wechatDepartment = new WechatDepartment();
        wechatDepartment.setId(id);
        wechatDepartment.setParentid(parentid);
        wechatDepartment.setName(name);
        wechatDepartment.setOrder(order);

        logger.info(String.format("微信修改部门请求：parentid %s name %s order %s", parentid, name, order));
        JSONObject jsonObject = httpPost(url, wechatDepartment);
        logger.info("微信修改部门响应：" + jsonObject);
    }

    private void deleteDepartments(HttpServletRequest request, List<Integer> departmentIds)
            throws Exception {

        if (departmentIds.isEmpty()) {
            return;
        }

        String url = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?access_token=" + this.accessToken(request, this.departmentSecret) + "&id=";

        for (Integer departmentId : departmentIds) {
            logger.info(String.format("微信删除部门请求：departmentId %s", departmentId));
            JSONObject jsonObject = httpGet(url + departmentId.toString());
            logger.info("微信修改部门响应：" + jsonObject);
        }
    }

    private void addUser(HttpServletRequest request, String userid, String name, String mobile, int department, String position, String gender, String email)
            throws Exception {

        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token=" + this.accessToken(request, this.departmentSecret);

        WechatUser wechatUser = new WechatUser();
        wechatUser.setUserid(userid);
        wechatUser.setName(name);
        wechatUser.setMobile(mobile);
        wechatUser.setDepartment(Arrays.asList(department));
        wechatUser.setPosition(position);
        wechatUser.setGender(gender);
        wechatUser.setEmail(email);

        logger.info(String.format("微信添加用户请求：userid %s name %s mobile %s department %s position %s gender %s email %s",
                userid, name, mobile, department, position, gender, email));
        JSONObject jsonObject = httpPost(url, wechatUser);
        logger.info("微信添加用户响应：" + jsonObject);
    }

    private void updateUser(HttpServletRequest request, String userid, String name, String mobile, int department, String position, String gender, String email)
            throws Exception {

        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/update?access_token=" + this.accessToken(request, this.departmentSecret);

        WechatUser wechatUser = new WechatUser();
        wechatUser.setUserid(userid);
        wechatUser.setName(name);
        wechatUser.setMobile(mobile);
        wechatUser.setDepartment(Arrays.asList(department));
        wechatUser.setPosition(position);
        wechatUser.setGender(gender);
        wechatUser.setEmail(email);

        logger.info(String.format("微信修改用户请求：userid %s name %s mobile %s department %s position %s gender %s email %s",
                userid, name, mobile, department, position, gender, email));
        JSONObject jsonObject = httpPost(url, wechatUser);
        logger.info("微信修改用户响应：" + jsonObject);
    }

    private void deleteUser(HttpServletRequest request, List<String> userIds)
            throws Exception {

        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/delete?access_token=" + this.accessToken(request, this.departmentSecret) + "&userid=";

        for (String userid : userIds) {

            logger.info(String.format("微信删除用户请求：userid %s", userid));
            JSONObject jsonObject = httpGet(url + userid);
            logger.info("微信删除用户响应：" + jsonObject);
        }
    }

    @Autowired
    private ReportCheckinDataService reportCheckinDataService;

    @RequestMapping("syncCheckinData")
    @ResponseBody
    public void syncCheckinData(HttpServletRequest request, Date start, Date end)
            throws Exception {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String url = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=" + this.accessToken(request, this.checkinSecret);

        Map<String, Object> map = new HashedMap();
        map.put("opencheckindatatype", 3);
        map.put("starttime", start);
        map.put("endtime", end);

        List<WechatUser> wUsers = this.getWechatUsers(request);
        List<String> userNames = new ArrayList<>();
        for (int i = 0; i < wUsers.size(); i++) {
            userNames.add((wUsers.get(i).getUserid()));
        }

        int pageSize = 50;
        int totalPage = (userNames.size() - 1) / pageSize + 1;
        for (int i = 0; i < totalPage; i++) {
            int fromIndex = i * pageSize;
            int toIndex = (i + 1) * pageSize;
            //toIndex = Integer.min(toIndex, userNames.size());
            toIndex = toIndex < userNames.size() ? toIndex : userNames.size();
            map.put("useridlist", userNames.subList(fromIndex, toIndex));

            JSONObject jsonObject = this.httpPost(url, map);
            String wCheckinString = jsonObject.getString("checkindata");
            Type type = new TypeToken<LinkedList<WechatCheckinData>>() {
            }.getType();
            Gson gson = this.createGson();
            List<WechatCheckinData> wCheckins = gson.fromJson(wCheckinString, type);
            for (WechatCheckinData wCheckin : wCheckins) {
                String userid = wCheckin.getUserid();
                JdbcTemplate jdbc = ContextHolder.getSpringBean("jdbcTemplate");
                String sql = "SELECT id FROM `app_user` WHERE NAME = '" + userid + "'";
                int result = jdbc.queryForList(sql, String.class).size();
                if (result != 0) {
                    ReportCheckinData checkinData = new ReportCheckinData();
                    checkinData.setUserName(wCheckin.getUserid());
                    checkinData.setGroupname(wCheckin.getGroupname());
                    checkinData.setCheckinType(wCheckin.getCheckin_type());
                    checkinData.setExceptionType(wCheckin.getException_type());
                    checkinData.setCheckinTime(wCheckin.getCheckin_time());
                    checkinData.setLocationTitle(wCheckin.getLocation_title());
                    checkinData.setLocationDetail(wCheckin.getLocation_detail());
                    checkinData.setWifiname(wCheckin.getWifiname());
                    checkinData.setNotes(wCheckin.getNotes());
                    checkinData.setWifimac(wCheckin.getWifimac());

                    JqGridRequest query = new JqGridRequest();
                    query.addFilterRule("user_name", JqGridFilterRuleOp.eq, checkinData.getUserName());
                    query.addFilterRule("checkin_time", JqGridFilterRuleOp.eq, formatter.format(checkinData.getCheckinTime()));
                    Long allCount = reportCheckinDataService.findAllCount(query.getFilter());
                    if (allCount == 0) {
                        reportCheckinDataService.saveOrUpdate(checkinData);
                    }
                }

            }
        }
    }

    @RequestMapping("syncCheckinData1")
    @ResponseBody
    public void syncCheckinData1(ServletContext servletContext, Date start, Date end)
            throws Exception {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String url = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata?access_token=" + this.accessToken1(servletContext, this.checkinSecret);

        Map<String, Object> map = new HashedMap();
        map.put("opencheckindatatype", 3);
        map.put("starttime", start);
        map.put("endtime", end);

        List<WechatUser> wUsers = this.getWechatUsers1(servletContext);
        List<String> userNames = new ArrayList<>();
        for (int i = 0; i < wUsers.size(); i++) {
            userNames.add((wUsers.get(i).getUserid()));
        }

        int pageSize = 50;
        int totalPage = (userNames.size() - 1) / pageSize + 1;
        for (int i = 0; i < totalPage; i++) {
            int fromIndex = i * pageSize;
            int toIndex = (i + 1) * pageSize;
            //toIndex = Integer.min(toIndex, userNames.size());
            toIndex = toIndex < userNames.size() ? toIndex : userNames.size();
            map.put("useridlist", userNames.subList(fromIndex, toIndex));

            JSONObject jsonObject = this.httpPost(url, map);
            String wCheckinString = jsonObject.getString("checkindata");
            Type type = new TypeToken<LinkedList<WechatCheckinData>>() {
            }.getType();
            Gson gson = this.createGson();
            List<WechatCheckinData> wCheckins = gson.fromJson(wCheckinString, type);
            for (WechatCheckinData wCheckin : wCheckins) {
                String userid = wCheckin.getUserid();
                JdbcTemplate jdbc = ContextHolder.getSpringBean("jdbcTemplate");
                String sql = "SELECT id FROM `app_user` WHERE NAME = '" + userid + "'";
                int result = jdbc.queryForList(sql, String.class).size();
                if (result != 0) {
                    ReportCheckinData checkinData = new ReportCheckinData();
                    checkinData.setUserName(wCheckin.getUserid());
                    checkinData.setGroupname(wCheckin.getGroupname());
                    checkinData.setCheckinType(wCheckin.getCheckin_type());
                    checkinData.setExceptionType(wCheckin.getException_type());
                    checkinData.setCheckinTime(wCheckin.getCheckin_time());
                    checkinData.setLocationTitle(wCheckin.getLocation_title());
                    checkinData.setLocationDetail(wCheckin.getLocation_detail());
                    checkinData.setWifiname(wCheckin.getWifiname());
                    checkinData.setNotes(wCheckin.getNotes());
                    checkinData.setWifimac(wCheckin.getWifimac());

                    JqGridRequest query = new JqGridRequest();
                    query.addFilterRule("user_name", JqGridFilterRuleOp.eq, checkinData.getUserName());
                    query.addFilterRule("checkin_time", JqGridFilterRuleOp.eq, formatter.format(checkinData.getCheckinTime()));
                    Long allCount = reportCheckinDataService.findAllCount(query.getFilter());
                    if (allCount == 0) {
                        reportCheckinDataService.saveOrUpdate(checkinData);
                    }
                }

            }
        }
    }
    
    @RequestMapping("toPageForMp")
    public ModelAndView toPageForMp(HttpServletRequest request, HttpServletResponse response) throws Exception {
      ModelAndView mv = new ModelAndView("api/wechat/incident/index2");  
      String code = request.getParameter("code");
      String appid = ContextHolder.getConfigByKey("wechatMpAppId");
      String secret=ContextHolder.getConfigByKey("wechatMpAppSecret");
      String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+secret+"&code="+code+"&grant_type=authorization_code";
      String openId="";
      String jsonString = "";
      
      try {
          JSONObject json = httpGet(url);
          jsonString = json.toString();
         
          openId=json.getString("openid");
          
      } catch (Exception e) {
          logger.error(e.getMessage(), e);
          throw new Exception("获取微信AccessToken失败，原因是：" + jsonString);
      }
      try {

          AppUser us=appUserService.findByOpenid(openId, "are_customer","mobile","name","fullname");
          if(us!=null)
          {
            boolean areCustomer=us.isAreCustomer();
            if(areCustomer)
            {
              String username=us.getName();
              openId=username;
              mv.setViewName("redirect:/api/wechat/incident/index2?openid="+openId+"&code="+code);
            }else
            {
              openId=us.getName();
              mv.setViewName("redirect:/wechat/index.html?code="+openId);
            }
          }else
          {
            mv.setViewName("redirect:/api/wechat/setting/register?openid="+openId);
          }
      } catch (Exception e) {
          e.printStackTrace();
          response.getWriter().append(e.getMessage());
      }
      
      return mv;
    }
    
    
    @RequestMapping("toPage")
    public ModelAndView toPage(HttpServletRequest request, HttpServletResponse response) throws Exception {
      ModelAndView mv = new ModelAndView("api/wechat/incident/index2");  
      String code = request.getParameter("code");
      
      String accessToken = this.accessToken(request, this.corpsecret);
      String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" + accessToken + "&code=" + code;
      String openId="";
      String jsonString = "";
      try {
          JSONObject json = httpGet(url);
          jsonString = json.toString();
          openId=json.getString("UserId");
          logger.info("toPage---------------openid:"+openId);
          logger.info("toPage---------------jsonString:"+jsonString);
      } catch (Exception e) {
          logger.error(e.getMessage(), e);
          throw new Exception("获取微信AccessToken失败，原因是：" + jsonString);
      }
      try {

          AppUser us=appUserService.findByOpenid(openId, "are_customer","mobile","name","fullname");
          if(us!=null)
          {
				/*
				 * boolean areCustomer=us.isAreCustomer(); if(areCustomer) { String
				 * username=us.getName(); openId=username;
				 * mv.setViewName("redirect:/api/wechat/incident/index2?openid="+openId+"&code="
				 * +code); }else { openId=us.getName();
				 * mv.setViewName("redirect:/wechat/index.html?code="+openId+"&code="+code); }
				 */
            String username=us.getName();
            openId=username;
            mv.setViewName("redirect:/api/wechat/incident/index2?openid="+openId+"&code="+code);
          }else
          {
            
          }
      } catch (Exception e) {
          e.printStackTrace();
          response.getWriter().append(e.getMessage());
      }
      
      return mv;
    }

    public void sendMessage(String message, String toUser, HttpServletRequest request)
            throws Exception {
        String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + this.accessToken(request, this.corpsecret);

        Map<String, String> text = new HashMap<>();
        text.put("content", message);

        Map<String, Object> map = new HashMap<>();
        map.put("touser", toUser);
        map.put("msgtype", "text");
        map.put("agentid", corpAgentId);
        map.put("text", text);

        JSONObject jsonObject = httpPost(url, map);
    }
    
    @RequestMapping("subscriptionLogin")
    public ModelAndView subscriptionLogin(String openid,HttpServletRequest request){
    	ModelAndView mv = new ModelAndView();
    	JdbcTemplate jdbcTemplate = ContextHolder.getSpringBean("jdbcTemplate");
    	String sql = "SELECT name FROM app_user WHERE openid=? limit 1";

    	List<Map<String, Object>> list=jdbcTemplate.queryForList(sql,openid);
    	if(list.size()>0)
    	{
    	  String username = list.get(0).get("name").toString();
    	  mv.setViewName("api/wechat/v2/wechat/toPage?code="+username); 
    	}else
    	{
    	  mv.setViewName("api/wechat/setting/register?openid="+openid);
    	}
    	return mv;
    }

    private class WechatDepartment {
        private int id;
        private String name;
        private int parentid;
        private int order;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getParentid() {
            return parentid;
        }

        public void setParentid(int parentid) {
            this.parentid = parentid;
        }

        public int getOrder() {
            return order;
        }

        public void setOrder(int order) {
            this.order = order;
        }
    }

    private class WechatUser {
        private String userid;
        private String name;
        private String mobile;
        private List<Integer> department;
        private String position;
        private String gender;
        private String email;

        public String getUserid() {
            return userid;
        }

        public void setUserid(String userid) {
            this.userid = userid;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getMobile() {
            return mobile;
        }

        public void setMobile(String mobile) {
            this.mobile = mobile;
        }

        public List<Integer> getDepartment() {
            return department;
        }

        public void setDepartment(List<Integer> department) {
            this.department = department;
        }

        public String getPosition() {
            return position;
        }

        public void setPosition(String position) {
            this.position = position;
        }

        public String getGender() {
            return gender;
        }

        public void setGender(String gender) {
            this.gender = gender;
        }

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }
    }

    private class WechatCheckinData {
        private String userid;
        private String groupname;
        private String checkin_type;
        private String exception_type;
        private Date checkin_time;
        private String location_title;
        private String location_detail;
        private String wifiname;
        private String notes;
        private String wifimac;

        public String getUserid() {
            return userid;
        }

        public void setUserid(String userid) {
            this.userid = userid;
        }

        public String getGroupname() {
            return groupname;
        }

        public void setGroupname(String groupname) {
            this.groupname = groupname;
        }

        public String getCheckin_type() {
            return checkin_type;
        }

        public void setCheckin_type(String checkin_type) {
            this.checkin_type = checkin_type;
        }

        public Date getCheckin_time() {
            return checkin_time;
        }

        public String getException_type() {
            return exception_type;
        }

        public void setException_type(String exception_type) {
            this.exception_type = exception_type;
        }

        public void setCheckin_time(Date checkin_time) {
            this.checkin_time = checkin_time;
        }

        public String getLocation_title() {
            return location_title;
        }

        public void setLocation_title(String location_title) {
            this.location_title = location_title;
        }

        public String getLocation_detail() {
            return location_detail;
        }

        public void setLocation_detail(String location_detail) {
            this.location_detail = location_detail;
        }

        public String getWifiname() {
            return wifiname;
        }

        public void setWifiname(String wifiname) {
            this.wifiname = wifiname;
        }

        public String getNotes() {
            return notes;
        }

        public void setNotes(String notes) {
            this.notes = notes;
        }

        public String getWifimac() {
            return wifimac;
        }

        public void setWifimac(String wifimac) {
            this.wifimac = wifimac;
        }
    }
}
